package com.chris.core.socket.netty.comm;

import io.netty.util.CharsetUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 字节码处理类
 */
public class ByteUtil {


    /**
     * String 转换为 byte
     *
     * @param s
     * @return
     */
    public static byte[] StringToByte(String s) {
        return s.getBytes(CharsetUtil.UTF_8);
    }

    /**
     * 字节码转成字符串
     *
     * @param bytes
     * @return
     */
    public static String ByteToString(byte[] bytes) {
        return new String(bytes, CharsetUtil.UTF_8);
    }

    /**
     * 转换int为byte数组
     *
     * @param x
     */
    public static byte[] IntToByte(int x) {
        byte[] bytes = new byte[4];
        bytes[3] = (byte) (x >> 24);
        bytes[2] = (byte) (x >> 16);
        bytes[1] = (byte) (x >> 8);
        bytes[0] = (byte) (x >> 0);
        return bytes;
    }

    /**
     * 通过byte数组取到int
     * byte[4]
     *
     * @param bb
     * @return
     */
    public static int ByteToInt(byte[] bb) {
        return (int) ((((bb[3] & 0xff) << 24)
                | ((bb[2] & 0xff) << 16)
                | ((bb[1] & 0xff) << 8) | ((bb[0] & 0xff) << 0)));
    }

    /**
     * 转换long型为byte数组
     * byte[4]
     *
     * @param x
     */
    public static byte[] LongToByte(long x) {
        byte[] bytes = new byte[8];
        bytes[7] = (byte) (x >> 56);
        bytes[6] = (byte) (x >> 48);
        bytes[5] = (byte) (x >> 40);
        bytes[4] = (byte) (x >> 32);
        bytes[3] = (byte) (x >> 24);
        bytes[2] = (byte) (x >> 16);
        bytes[1] = (byte) (x >> 8);
        bytes[0] = (byte) (x >> 0);
        return bytes;
    }

    /**
     * 通过byte数组取到long
     * byte[8]
     *
     * @param bb
     * @return
     */
    public static long ByteToLong(byte[] bb) {
        return ((((long) bb[7] & 0xff) << 56)
                | (((long) bb[6] & 0xff) << 48)
                | (((long) bb[5] & 0xff) << 40)
                | (((long) bb[4] & 0xff) << 32)
                | (((long) bb[3] & 0xff) << 24)
                | (((long) bb[2] & 0xff) << 16)
                | (((long) bb[1] & 0xff) << 8)
                | (((long) bb[0] & 0xff) << 0));
    }

    /**
     * 字符到字节转换
     *
     * @param ch
     * @return
     */
    public static byte[] CharToByte(char ch) {
        int temp = (int) ch;
        byte[] bytes = new byte[2];
        for (int i = 0; i < 2; i++) {
            bytes[i] = new Integer(temp & 0xff).byteValue(); // 将最高位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return bytes;
    }

    /**
     * 字节到字符转换
     *
     * @param b
     * @return
     */
    public static char ByteToChar(byte[] b) {
        int s = 0;
        if (b[1] > 0)
            s += b[1];
        else
            s += 256 + b[0];
        s *= 256;
        if (b[0] > 0)
            s += b[1];
        else
            s += 256 + b[0];
        char ch = (char) s;
        return ch;
    }

    /**
     * float转换byte
     *
     * @param x
     */
    public static byte[] FloatToByte(float x) {
        byte[] bytes = new byte[4];
        int l = Float.floatToIntBits(x);
        for (int i = 0; i < 4; i++) {
            bytes[i] = new Integer(l).byteValue();
            l = l >> 8;
        }
        return bytes;
    }

    /**
     * 通过byte数组取得float
     * byte[4]
     *
     * @param bytes
     * @return
     */
    public static float ByteToFloat(byte[] bytes) {
        int l;
        l = bytes[0];
        l &= 0xff;
        l |= ((long) bytes[1] << 8);
        l &= 0xffff;
        l |= ((long) bytes[2] << 16);
        l &= 0xffffff;
        l |= ((long) bytes[3] << 24);
        return Float.intBitsToFloat(l);
    }

    /**
     * double转换byte
     * byte[8]
     *
     * @param x
     */
    public static byte[] DoubleToByte(double x) {
        byte[] bytes = new byte[8];
        long l = Double.doubleToLongBits(x);
        for (int i = 0; i < 8; i++) {
            bytes[i] = new Long(l).byteValue();
            l = l >> 8;
        }
        return bytes;
    }

    /**
     * 通过byte数组取得double
     *
     * @param b
     * @return
     */
    public static double ByteToDouble(byte[] b) {
        long l;
        l = b[0];
        l &= 0xff;
        l |= ((long) b[1] << 8);
        l &= 0xffff;
        l |= ((long) b[2] << 16);
        l &= 0xffffff;
        l |= ((long) b[3] << 24);
        l &= 0xffffffffl;
        l |= ((long) b[4] << 32);
        l &= 0xffffffffffl;
        l |= ((long) b[5] << 40);
        l &= 0xffffffffffffl;
        l |= ((long) b[6] << 48);
        l &= 0xffffffffffffffl;
        l |= ((long) b[7] << 56);
        return Double.longBitsToDouble(l);
    }


    /**
     * 对象转Byte数组
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static byte[] ObjectToBytes(Object obj) throws Exception {
        //
        // logger.debug("objectToString called ");
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream sOut = new ObjectOutputStream(out);
        sOut.writeObject(obj);
        sOut.flush();
        byte[] bytes = out.toByteArray();

        // logger.debug(bytes.toString());

        return bytes;
    }

    /**
     * 字节数组转对象
     * @param bytes
     * @return
     * @throws Exception
     */
    public static Object BytesToObject(byte[] bytes) throws Exception {
       // logger.debug("bytesToObject called ");
       //byte转object
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        ObjectInputStream sIn = new ObjectInputStream(in);
        return sIn.readObject();

    }


}
